package com.haifeng.sbtx.auth.config;

import com.alibaba.fastjson.JSON;
import com.haifeng.sbtx.common.util.CryptoUtil;
import com.haifeng.sbtx.mapper.entity.dto.UserDto;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;

import java.util.Random;
import java.util.UUID;

/**
 * 自定义token
 */
public class CustomTokenEnhancer implements TokenEnhancer {
    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        if (accessToken instanceof DefaultOAuth2AccessToken) {
            Authentication userAuthentication = authentication.getUserAuthentication();
            DefaultOAuth2AccessToken token = ((DefaultOAuth2AccessToken) accessToken);
            OAuth2RefreshToken refreshToken = token.getRefreshToken();
            if (null == userAuthentication){
                token.setValue(getNewToken(null));
                if (refreshToken instanceof DefaultOAuth2RefreshToken) {
                    token.setRefreshToken(new DefaultOAuth2RefreshToken(getNewToken(null)));
                }
            }else {
                UserDto user = (UserDto) authentication.getPrincipal();
                token.setValue(getNewToken(user.getUsername() + ","));
                if (refreshToken instanceof DefaultOAuth2RefreshToken) {
                    token.setRefreshToken(new DefaultOAuth2RefreshToken(getNewToken(user.getId() + ",")));
                }
            }
            return token;
        }
        return accessToken;
    }

    private static String getNewToken(String username) {
        String str = UUID.randomUUID().toString() + getItemID();
        return CryptoUtil.encoder(JSON.toJSONString(username + str));
    }

    private static String getItemID() {
        StringBuilder val = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 8; i++) {
            String str = random.nextInt(2) % 2 == 0 ? "num" : "char";
            if ("char".equalsIgnoreCase(str)) {
                int nextInt = random.nextInt(2) % 2 == 0 ? 65 : 97;
                val.append((char) (nextInt + random.nextInt(26)));
            } else {
                val.append(String.valueOf(random.nextInt(10)));
            }
        }
        return val.toString();
    }
}
